package com.tangbuzhi.abstract_factory;

/**
 * 抽象工厂
 */
public class AbstractFactory {
    /**
     * 产品类接口
     */
    public interface Computer {
        void create();
    }

    /**
     * 具体产品实现类1
     */
    public static class HpComputer implements Computer {
        @Override
        public void create() {
            System.out.println("create a Hp computer");
        }
    }

    /**
     * 具体产品实现类2
     */
    public static class LenovoComputer implements Computer {
        @Override
        public void create() {
            System.out.println("create a Lenovo computer");
        }
    }

    /**
     * 工厂类接口方法一
     */
    public interface IFactory {
        Computer prouceComputer();
    }

    /**
     * 具体工厂实现类1
     */
    public static class HpFactory implements IFactory {
        @Override
        public Computer prouceComputer() {
            return new HpComputer();
        }
    }

    /**
     * 具体工厂实现类2
     */
    public static class LenovoFactory implements IFactory {
        @Override
        public Computer prouceComputer() {
            return new LenovoComputer();
        }
    }

    /**
     * 抽象工厂类接口方法二
     */
    public interface ComputerFactory {
        <T extends Computer> T produceComputer(Class<T> clz);
    }

    /**
     * 具体工厂实现类方法二
     */
    public static class ConcreteComputerFactory implements ComputerFactory {
        @Override
        public <T extends Computer> T produceComputer(Class<T> clz) {
            try {
                Computer computer = (Computer) Class.forName(clz.getName()).newInstance();
                return (T) computer;
            } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
                e.printStackTrace();
                return null;
            }
        }
    }

    public static void main(String[] args) {
        HpFactory hpFactory = new HpFactory();
        hpFactory.prouceComputer().create();

        LenovoFactory lenovoFactory = new LenovoFactory();
        lenovoFactory.prouceComputer().create();

        System.out.println("=======================================");
        ComputerFactory computerFactory = new ConcreteComputerFactory();
        HpComputer hpComputer = computerFactory.produceComputer(HpComputer.class);
        hpComputer.create();
        LenovoComputer lenovoComputer = computerFactory.produceComputer(LenovoComputer.class);
        lenovoComputer.create();
    }
}
